package com.titaniume.activitiweb.controller;

import com.titaniume.activitiweb.SecurityUtil;
import com.titaniume.activitiweb.pojo.UserInfoBean;
import com.titaniume.activitiweb.util.AjaxResponse;
import com.titaniume.activitiweb.util.GlobalConfig;
import org.activiti.api.model.shared.model.VariableInstance;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @ProjectName: activiti7_workflow
 * @Package: com.titaniume.activitiweb.controller
 * @ClassName: ProcessInstanceController
 * @Author: huangrenfei
 * @Description: 流程实例
 * @Date: 2021/11/16 10:15
 * @Version: 1.0
 */
@RestController
@RequestMapping("/processInstance")
public class ProcessInstanceController {


    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private SecurityUtil securityUtil;

    @Autowired
    private ProcessRuntime processRuntime;

    //查询流程实例
    @GetMapping(value = "/getInstances")
    public AjaxResponse getInstance(@AuthenticationPrincipal UserInfoBean userInfoBean) {
        try {
            //开发阶段模拟登录
            if (GlobalConfig.Test) {
                securityUtil.logInAs("bajie");
            }
            Page<ProcessInstance> processInstance = processRuntime.processInstances(Pageable.of(0, 100));
            List<ProcessInstance> list = processInstance.getContent();
            list.sort((x, y) -> x.getStartDate().toString().compareTo(y.getStartDate().toString()));
            List<HashMap<String, Object>> listMap = new ArrayList<HashMap<String, Object>>();
            for (ProcessInstance instance : list) {
                HashMap<String, Object> hashMap = new HashMap<>();
                hashMap.put("id", instance.getId());
                hashMap.put("name", instance.getName());
                hashMap.put("status", instance.getStatus());
                hashMap.put("processDefinitionId", instance.getProcessDefinitionId());
                hashMap.put("processDefinitionKey", instance.getProcessDefinitionKey());
                hashMap.put("startDate", instance.getStartDate());
                hashMap.put("processDefinitionVersion", instance.getProcessDefinitionVersion());

                //因为instance 没有历史高亮需要的DeploymentID 和资源Name，需要再次查询 （不推荐for循环里面写查询 ，推荐自己写sql）
                ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                        .processDefinitionId(instance.getProcessDefinitionId())
                        .singleResult();

                hashMap.put("deploymentId", processDefinition.getDeploymentId());
                hashMap.put("resourceName", processDefinition.getResourceName());
                listMap.add(hashMap);
            }
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),
                    GlobalConfig.ResponseCode.SUCCESS.getDesc(),
                    listMap);
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),
                    "获取流程实例失败",
                    e.toString());
        }
    }

    //启动流程实例
    @GetMapping(value = "/startProcess")
    public AjaxResponse startProcess(@RequestParam("processDefinitionKey") String processDefinitionKey
            , @RequestParam("instanceName") String instanceName) {
        try {
            //开发阶段模拟登录
            if (GlobalConfig.Test) {
                securityUtil.logInAs("bajie");
            } else {
                //获取登录人名称
                securityUtil.logInAs(SecurityContextHolder.getContext().getAuthentication().getName());
            }
            processRuntime.start(ProcessPayloadBuilder
                    .start()
                    .withProcessDefinitionKey(processDefinitionKey)
                    .withName(instanceName)
                    .withBusinessKey("自定义BussinessKey")
//                    .withVariable("参数name","参数value")
                    .build());

            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),
                    GlobalConfig.ResponseCode.SUCCESS.getDesc(),
                    null);
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),
                    "启动流程实例失败",
                    e.toString());
        }
    }

    //挂起流程实例
    @GetMapping(value = "/suspendInstance")
    public AjaxResponse suspendInstance(@RequestParam("instanceID") String instanceID) {
        try {
            if (GlobalConfig.Test) {
                securityUtil.logInAs("bajie");
            }

            ProcessInstance processInstance = processRuntime.suspend(ProcessPayloadBuilder
                    .suspend()
                    .withProcessInstanceId(instanceID)
                    .build());

            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),
                    GlobalConfig.ResponseCode.SUCCESS.getDesc(),
                    processInstance.getName());
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),
                    "暂停流程实例失败",
                    e.toString());
        }
    }

    //激活/重启流程实例
    @GetMapping(value = "/resumeInstance")
    public AjaxResponse resumeInstance(@RequestParam("instanceID") String instanceID) {
        try {
            if (GlobalConfig.Test) {
                securityUtil.logInAs("bajie");
            }

            ProcessInstance processInstance = processRuntime.resume(ProcessPayloadBuilder
                    .resume()
                    .withProcessInstanceId(instanceID)
                    .build());

            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),
                    GlobalConfig.ResponseCode.SUCCESS.getDesc(),
                    processInstance.getName());
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),
                    "激活流程实例失败",
                    e.toString());
        }
    }

    //删除流程实例
    @GetMapping(value = "/deleteInstance")
    public AjaxResponse deleteInstance(@RequestParam("instanceID") String instanceID) {
        try {
            if (GlobalConfig.Test) {
                securityUtil.logInAs("bajie");
            }

            ProcessInstance processInstance = processRuntime.delete(ProcessPayloadBuilder
                    .delete()
                    .withProcessInstanceId(instanceID)
                    .build());

            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),
                    GlobalConfig.ResponseCode.SUCCESS.getDesc(),
                    processInstance.getName());
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),
                    "删除流程实例失败",
                    e.toString());
        }
    }

    //查询流程参数
    @GetMapping(value = "/variables")
    public AjaxResponse variables(@RequestParam("instanceID") String instanceID) {
        try {
            if (GlobalConfig.Test) {
                securityUtil.logInAs("bajie");
            }

            List<VariableInstance> variableInstances = processRuntime.variables(ProcessPayloadBuilder
                    .variables()
                    .withProcessInstanceId(instanceID)
                    .build());

            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),
                    GlobalConfig.ResponseCode.SUCCESS.getDesc(),
                    variableInstances);
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),
                    "查询流程实例参数失败",
                    e.toString());
        }
    }



}
